#ifndef CHIP8_H
#define CHIP8_H

// Memory Mapping for Chip-8
// +---------------+= 0xFFF (4095) End of Chip-8 RAM
// |               |
// |               |
// |               |
// |               |
// |               |
// | 0x200 to 0xFFF|
// |     Chip-8    |
// | Program / Data|
// |     Space     |
// |               |
// |               |
// |               |
// +- - - - - - - -+= 0x600 (1536) Start of ETI 660 Chip-8 programs
// |               |
// |               |
// |               |
// +---------------+= 0x200 (512) Start of most Chip-8 programs
// | 0x000 to 0x1FF|
// | Reserved for  |
// |  interpreter  |
// +---------------+= 0x000 (0) Start of Chip-8 RAM

// Chip-8 Keypad Mapping
// 1  2  3  C
// 4  5  6  D
// 7  8  9  E
// A  0  B  F

#define CHIP8_MEMORY_SIZE       4096
#define CHIP8_PRG_OFFSET        0x200
#define CHIP8_FONT_OFFSET       0x50
#define CHIP8_RESERVED_OFFSET   0xEA0
#define CHIP8_STACK_SIZE        16
#define CHIP8_SCR_WIDTH         64
#define CHIP8_SCR_HEIGHT        32
#define CHIP8_SCR_SCALE         15
#define RESULT_OK               0
#define RESULT_FAIL             !RESULT_OK
#define FALSE                   0
#define TRUE                    !FALSE

typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef void                (*CHIP8_INSTRUCTION_CALLBACK)       (WORD);
typedef void                (*CHIP8_SCREEN_UPDATE_CALLBACK)     (BYTE [CHIP8_SCR_WIDTH][CHIP8_SCR_HEIGHT]);
typedef void                (*CHIP8_SOUND_CALLBACK)             (void);
typedef void                (*CHIP8_ASSEMBLY_DUMP_CALLBACK)     (const WORD, const WORD, const char*);

extern BYTE g_keys[16];

int     chip8_init  (const char*, 
                     CHIP8_SCREEN_UPDATE_CALLBACK, 
                     CHIP8_SOUND_CALLBACK,
                     CHIP8_ASSEMBLY_DUMP_CALLBACK);

void    chip8_cycle ();

#endif
